﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using StockFinder.Model;
using System.Net;
using System.IO;
using System.Net.Cache;
using System.Web;
using HtmlAgilityPack;
using System.Xml;

namespace StockFinder.Services.Extractors.IBD
{
    /// <summary>
    /// Extracts a list of symbols from IBD that meet the specified IBD composite rating
    /// </summary>
    public class IBDSymbolsByCompositeRatingExtractor
    {
        public IBDSymbolsByCompositeRatingExtractor()
        {

        }

        /// <summary>
        /// Extracts a list of symbols and their ratings based on IBD composite rating
        /// </summary>
        /// <param name="rating"></param>
        /// <returns></returns>
        public List<IBDRatings> GetByCompositeRating(int rating)
        {
            List<IBDRatings> ibdRatings = new List<IBDRatings>();

            #region Web lookup variables

            HttpWebRequest webRequest;
            HttpWebResponse webResponse;
            string pageSource = string.Empty;
            CookieContainer cookieContainer = new CookieContainer();

            #endregion

            #region Login to get cookies

            string loginUrl = "http://www.investors.com/Services/SiteAjaxService.asmx/MemberSingIn?strEmail=ssattin@gmail.com&strPassword=dennis10&blnRemember=false";

            webRequest = (HttpWebRequest)(WebRequest.Create(loginUrl));
            webRequest.CookieContainer = cookieContainer;
            webRequest.Accept = "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-silverlight, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, #/#";
            webRequest.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5";
            webRequest.KeepAlive = true;
            webRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;
            webRequest.Method = "GET";
            webRequest.ContentType = "application/x-www-form-urlencoded";
            webResponse = (HttpWebResponse)webRequest.GetResponse();

            //get the response details
            using (StreamReader streamReader = new StreamReader(webResponse.GetResponseStream()))
            {
                //get the page response
                pageSource = streamReader.ReadToEnd();

                //write the response to diagnostic file
                using (StreamWriter writer = new StreamWriter(new FileStream("testlogin.xml", FileMode.Create)))
                {
                    writer.Write(pageSource);
                }
            }

            webResponse.Close();

            #endregion

            #region Get the composite ratings page

            Byte[] postData = Encoding.UTF8.GetBytes(string.Format("csID=&csName=New+Custom+Screen&getRS=0&hidLastForm=Run1&hidSmrtEPSMin=&hidSmrtEPSMax=&hidSmrtRlstMin=&hidSmrtRlstMax=&hidSmrtGrpReld=&hidSmrtSMRL=&hidSmrtAccDis=&hidSmrtCompMin={0}&hidSmrtCompMax={0}&hidInGpBrCdInc=&hidInGpBrCd=&hidInGpInCdInc=&hidInGpInCd=&hidInGpRnkMin=&hidInGpRnkMax=&hidShrSharesMin=&hidShrSharesMax=&hidShrMktVatMin=&hidShrMktVatMax=&hidShrSponsor=&hidShrFundsMin=&hidShrFundsMax=&hidShrFundsHoldMin=&hidShrFundsHoldMax=&hidPVolPriceMin=&hidPVolPriceMax=&hidPVolAtHigh=&hidPVolPOffMin=&hidPVolPOffMax=&hidPVolAvolMin=&hidPVolAvolMax=&hidPVolVolIncrMin=&hidPVolVolIncrMax=&hidPVolPChg10Min=&hidPVolPChg10Max=&hidPVolPChg200Min=&hidPVolPChg200Max=&hidPVolPup6Min=&hidPVolPup6Max=&hidPVolPup12Min=&hidPVolPup12Max=&hidPVolPupMin=&hidPVolPupMax=&hidPVolAlphaMin=&hidPVolAlphaMax=&hidPVolBetaMin=&hidPVolBetaMax=&hidErnEiqyMin=&hidErnEiqyMax=&hidErnEIQYZ=&hidErnFcqpMin=&hidErnFcqpMax=&hidErnFcfypMin=&hidErnFcfypMax=&hidErnFcfyp1Min=&hidErnFcfyp1Max=&hidErnAccEPS=&hidErnEPSGr3Min=&hidErnEPSGr3Max=&hidErnEPSGr5Min=&hidErnEPSGr5Max=&hidErnAvEPS2Min=&hidErnAvEPS2Max=&hidErnAvEPS3Min=&hidErnAvEPS3Max=&hidErnAvEPS4Min=&hidErnAvEPS4Max=&hidErnAvEPS5Min=&hidErnAvEPS5Max=&hidErnAvEPS6Min=&hidErnAvEPS6Max=&hidSlsASalesMin=&hidSlsASalesMax=&hidSlsSIQYMin=&hidSlsSIQYMax=&hidSlsSIYYMin=&hidSlsSIYYMax=&hidSlsAccSales=&hidSlsAvSal2Min=&hidSlsAvSal2Max=&hidSlsAvSal3Min=&hidSlsAvSal3Max=&hidSlsAvSal4Min=&hidSlsAvSal4Max=&hidSlsAvSal5Min=&hidSlsAvSal5Max=&hidSlsAvSal6Min=&hidSlsAvSal6Max=&hidSlsSgr3YrMin=&hidSlsSgr3YrMax=&hidSlsSalGrtMin=&hidSlsSalGrtMax=&hidRtioMarQMin=&hidRtioMarQMax=&hidRtioMarQ1Min=&hidRtioMarQ1Max=&hidRtioMarQ2Min=&hidRtioMarQ2Max=&hidRtioMarQ3Min=&hidRtioMarQ3Max=&hidRtioMarQ4Min=&hidRtioMarQ4Max=&hidRtioMarQ5Min=&hidRtioMarQ5Max=&hidRtioAccMar=&hidRtioPTMarMin=&hidRtioPTMarMax=&hidRtioROEMin=&hidRtioROEMax=&hidRtioDebtMin=&hidRtioDebtMax=&hidRtioEstPEMin=&hidRtioEstPEMax=&hidRtioCurPEMin=&hidRtioCurPEMax=&hidRtioMarBkMin=&hidRtioMarBkMax=&hidRtioYieldMin=&hidRtioYieldMax=&hidNoRegDividends=&hidGenExch=&hidGenCanadian=&hidGenForeign=&hidGenSP500F=&hidGenOpt=&hidGenOptA=&hidGenOptC=&hidGenOptPh=&hidGenOptPa=&hidGenIPOYrMin=&hidGenIPOYrMax=&hidGenYrIncMin=&hidGenYrIncMax=&hidGenCity=&hidGenState=&hidGenCEO=&hidGenIBD=&hidStrSql=+from+x+where+%7B6027%7D%3D1++and+%28%28%7B6719%7D+%3D+{0}%29+%29+and+%7B1044%7D+in+%281%2C2%2C3%2C4%2C80%2C81%2C82%29+&hidReturnURL=csSmrt.asp&hidTotalCount=51&hidBlnUseIntraDay=True&sort1=symbol&order1=1&sort2=&order2=1", rating.ToString()));
            webRequest = (HttpWebRequest)(WebRequest.Create("http://premium.investors.com/member/customscreen/csRun2.asp"));
            webRequest.CookieContainer = cookieContainer;
            webRequest.Accept = "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-silverlight, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, #/#";
            webRequest.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5";
            webRequest.KeepAlive = true;
            webRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;
            webRequest.Method = "POST";
            webRequest.ContentType = "application/x-www-form-urlencoded";
            webRequest.ContentLength = postData.Length;

            //write the data to the stream
            Stream requestStream = webRequest.GetRequestStream();
            requestStream.Write(postData, 0, postData.Length);
            requestStream.Close();
            webResponse = (HttpWebResponse)webRequest.GetResponse();

            //get the response details
            using (StreamReader streamReader = new StreamReader(webResponse.GetResponseStream()))
            {
                //get the page response
                //pageSource = HttpUtility.HtmlEncode(streamReader.ReadToEnd());
                pageSource = (streamReader.ReadToEnd());

                //write the response to diagnostic file
                using (StreamWriter writer = new StreamWriter(new FileStream(string.Format("compositerating{0}.html", rating), FileMode.Create)))
                {
                    writer.Write(pageSource);
                }
            }

            webResponse.Close();

            #endregion

            #region Format result page source

            //parse the downloaded html document
            HtmlDocument htmlDocument = new HtmlDocument();
            htmlDocument.LoadHtml(pageSource);

            //find the input tag hXMLRS
            HtmlNode xmlNode = htmlDocument.DocumentNode.SelectSingleNode("//input[@name=\"hXMLRS\"]");

            //set up the result string
            string result = xmlNode.OuterHtml.Replace("<input type=\"hidden\" name=\"hXMLRS\" value=\"", "");
            result = result.Replace("\">", "");
            result = result.Replace("&lt;", "<");
            result = result.Replace("&gt;", ">");
            result = result.Replace("z:row", "symboldata");

            #endregion

            #region Extract IBD ratings

            //load the result into an xml document
            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.LoadXml(result);

            //find the "z:row" inner nodes
            XmlNodeList symbolNodes = xmlDocument.SelectNodes("//symboldata");

            //loop the symbols
            foreach (XmlNode node in symbolNodes)
            {
                ibdRatings.Add(new IBDRatings()
                {
                    Symbol = GetValueFromNodeAttribute<string>(node.Attributes["Symbol"]),
                    EPS = GetValueFromNodeAttribute<int>(node.Attributes["EPS"]),
                    RelativeStrength = GetValueFromNodeAttribute<int>(node.Attributes["RS"]),
                    GroupRSRating = GetValueFromNodeAttribute<string>(node.Attributes["GrpRS"]),
                    SMR = GetValueFromNodeAttribute<string>(node.Attributes["SMR"]),
                    AccDist = GetValueFromNodeAttribute<string>(node.Attributes["AccDis"]),
                    IBDComposite = rating,
                    Date = DateTime.Now.Date
                });
            }

            #endregion          

            #region Extract IBD rating info

            //if (!string.IsNullOrEmpty(pageSource))
            //{
            //    pageSource = pageSource.Replace("\n", "");
            //    pageSource = pageSource.Replace("\r", "");
            //    pageSource = pageSource.Replace("\t", "");
            //    pageSource = pageSource.Replace(" ", "");
            //    pageSource = pageSource.Replace("</table></BODY></HTML>", "");

            //    //split into table rows
            //    string[] lines = pageSource.Split(new string[] { "<tr>" }, StringSplitOptions.None);

            //    foreach (string line in lines)
            //    {
            //        //ignore table headers
            //        if (line.StartsWith("<td>"))
            //        {
            //            //splt into table cells
            //            string[] cells = line.Split(new string[] { "<td>" }, StringSplitOptions.None);

            //            ibdRatings.Add(new IBDRatings()
            //            {
            //                Symbol = cells[1].Replace("</td>", "").Trim(),
            //                IBDComposite = rating,
            //                EPS = Convert.ToInt32(cells[7].Replace("</td>", "").Trim()),
            //                RelativeStrength = Convert.ToInt32(cells[8].Replace("</td>", "").Trim()),
            //                GroupRSRating = cells[9].Replace("</td>", "").Trim(),
            //                SMR = cells[10].Replace("</td>", "").Trim(),
            //                AccDist = cells[11].Replace("</td>", "").Trim()
            //            });
                           
            //        }
            //    }
            //}

            #endregion

            return ibdRatings;
        }

        private T GetValueFromNodeAttribute<T>(XmlAttribute attribute)
        {
            T returnValue = default(T);

            if (attribute != null)
            {
                returnValue = (T)Convert.ChangeType(attribute.Value.Trim(), typeof(T));
            }
            else
            {

            }

            return returnValue;
        }
    }   
}